package element.synt;

import element.base.Synt;
import element.base.TreeNode;
import intermediate_representation.AssignRP;
import intermediate_representation.DefineRP;
import symbal.Symbal;
import symbal.Vtype;
import symbal.constsymbal.ConstInt;
import symbal.constsymbal.ConstInt1;
import symbal.constsymbal.ConstInt2;
import symbal.constsymbal.ConstSymbal;
import table.InterCodeTable;

import java.util.ArrayList;

//ConstDecl → 'const' BType ConstDef { ',' ConstDef } ';'
//ConstDef → Ident { '[' ConstExp ']' } '=' ConstInitVal
public class ConstDecl extends Synt {
    @Override
    public void tointerRP() {
        ArrayList<TreeNode> nodes = this.getNodes();
        int loop = (nodes.size() - 2) / 2;
        for (int i = 0; i < loop; i++) {
            int index = 2 * i + 2;
            ConstDef constDef = (ConstDef) nodes.get(index);
            String name = constDef.findFirst().getContent();
            ArrayList<TreeNode> defnodes = constDef.getNodes();
            int subloop = (defnodes.size() - 3) / 3;
            if (subloop == 0) {
                Symbal symbal = new Symbal(name, Vtype.INT);
                symbal.setConsts();
                String mipsname = "const" + InterCodeTable.constnum;
                symbal.setMipsName(mipsname);
                InterCodeTable.constnum++;
                InterCodeTable.symbalTable.addSymbal(symbal);

                DefineRP defineRP = new DefineRP(true, mipsname);
                InterCodeTable.addCode(defineRP);

                ConstInitVal initVal = (ConstInitVal) defnodes.get(2);
                String value0 = initVal.getvalue0();
                AssignRP assignRP = new AssignRP(mipsname, value0);
                InterCodeTable.addCode(assignRP);

                ConstSymbal constSymbal = new ConstInt(name, Integer.parseInt(value0));
                InterCodeTable.constTable.addSymbal(constSymbal);
                if (InterCodeTable.global) {
                    InterCodeTable.globalTable.addSymbal(constSymbal);
                }

            } else if (subloop == 1) {
                ConstExp len1exp = (ConstExp) defnodes.get(2);
                int len1 = len1exp.calcu();
                Symbal symbal = new Symbal(name, Vtype.INT1);
                symbal.setConsts();
                String mipsname = "const" + InterCodeTable.constnum;
                symbal.setMipsName(mipsname);
                InterCodeTable.constnum++;
                symbal.setLen1(len1);
                InterCodeTable.symbalTable.addSymbal(symbal);

                DefineRP defineRP = new DefineRP(true, mipsname, len1);
                InterCodeTable.addCode(defineRP);

                ConstInitVal initVal = (ConstInitVal) defnodes.get(5);
                ArrayList<String> value1 = initVal.getvalue1(len1);
                for (int j = 0; j < len1; j++) {
                    String unit = mipsname + "[" + j + "]";
                    AssignRP assignRP = new AssignRP(unit, value1.get(j));
                    InterCodeTable.addCode(assignRP);
                }

                ConstSymbal constSymbal = new ConstInt1(name, value1);
                InterCodeTable.constTable.addSymbal(constSymbal);
                if (InterCodeTable.global) {
                    InterCodeTable.globalTable.addSymbal(constSymbal);
                }
            } else if (subloop == 2) {
                ConstExp len1exp = (ConstExp) defnodes.get(2);
                ConstExp len2exp = (ConstExp) defnodes.get(5);
                int len1 = len1exp.calcu();
                int len2 = len2exp.calcu();
                Symbal symbal = new Symbal(name, Vtype.INT2);
                symbal.setConsts();
                String mipsname = "const" + InterCodeTable.constnum;
                symbal.setMipsName(mipsname);
                InterCodeTable.constnum++;
                symbal.setLen1(len1);
                symbal.setLen2(len2);
                InterCodeTable.symbalTable.addSymbal(symbal);

                DefineRP defineRP = new DefineRP(true, mipsname, len1, len2);
                InterCodeTable.addCode(defineRP);

                ConstInitVal initVal = (ConstInitVal) defnodes.get(8);
                ArrayList<ArrayList<String>> value2 = initVal.getValue2(len1, len2);
                for (int j = 0; j < len1; j++) {
                    for (int k = 0; k < len2; k++) {
                        int point = j * len2 + k;
                        String unit = mipsname + "[" + point + "]";
                        AssignRP assignRP = new AssignRP(unit, value2.get(j).get(k));
                        InterCodeTable.addCode(assignRP);
                    }
                }

                ConstSymbal constSymbal = new ConstInt2(name, value2);
                InterCodeTable.constTable.addSymbal(constSymbal);
                if (InterCodeTable.global) {
                    InterCodeTable.globalTable.addSymbal(constSymbal);
                }
            }
        }
    }
}
